// gulp 打包的配置文件
// 导入 gulp 第三方包来实现打包配置的书写
const gulp = require('gulp')
const cssmin = require('gulp-cssmin')
const autoprefixer = require('gulp-autoprefixer')
const uglify = require('gulp-uglify')
const babel = require('gulp-babel')
const fileinclude = require('gulp-file-include')
const htmlmin = require('gulp-htmlmin')
const del = require('del')

/*
  1. 配置一个 打包 css 文件的任务
    => 思路
      -> 创建一个打包 css 文件的任务
      -> 在任务内书写
        + 找到源文件
        + 进行打包操作
        + 转存到 dist 目录内
    => 如何执行任务
      -> 打开命令行, 切换目录到你的项目根目录
      -> 输入指令: $ gulp 任务名称
    => 注意: 以上代码是 gulp 3.x.x 的版本的书写语法
*/
// gulp.task('cssHandler', () => {
//   // 书写打包 css 的任务流程
//   gulp
//     .src('./src/css/*.css')
//     // .pipe() // 进行打包操作
//     .pipe(gulp.dest('./dist/css/')) // 存储到指定位置
// })

/*
  1. 配置一个 打包 css 文件的任务
    => 不在依赖于 gulp.task 函数了
    => 可以直接定义函数来使用
    => 注意: 书写完毕以后, 你需要执行一步导出的操作

    => 如何对 css 文件进行打包操作
      + 依赖一个叫做 gulp-cssmin 的第三方, 来完成 css 文件的打包操作
      + 这个 gulp-cssmin 导入以后得到的就是一个函数
        -> 直接调用就可以对 css 文件进行打包

    => 在任务中多增加一个步骤(自动添加前缀)
      + 依赖一个叫做 gulp-autoprefixer 的第三方包来完成自动添加前缀功能
      + 导入以后, 你得到的就是一个函数, 直接调用就可以进行自动添加前缀
        -> 需要传递参数
        -> 参数: { browsers: [ '你要兼容的浏览器' ] }
      + 注意: 可以把配置项移动到 package.json 内书写
        "browserslist": [ "你要兼容到的浏览器" ]
*/
const cssHandler = () => {
  // 书写打包 css 的任务流程
  // 需要让 gulp 工具能够跟随到这个任务流
  // 需要把整个任务流 return 出去
  return gulp
    .src('./src/css/*.css')
    .pipe(autoprefixer()) // 自动添加前缀
    .pipe(cssmin()) // 进行打包操作
    .pipe(gulp.dest('./dist/css/')) // 存储到指定位置
}


/*
  3. 打包 js 文件的任务
    + 压缩 js 文件需要使用一个第三方包
      => 叫做 gulp-uglify
      => 下载导入以后就是一个函数, 直接调用就可以了
      => 注意: 不能对 es6 语法进行压缩处理
    + 需要多做一步操作
      => 把 es6 代码转换成 es5 代码
      => 转换 ES5 语法需要使用到的第三方包叫做 gulp-babel
    + 注意:
      1. 下载的时候需要下载三个第三方包
        => npm i -D gulp-babel
        => npm i -D @babel/core
        => npm i -D @babel/preset-env
      2. 导入的时候, 只需要导入一个 gulp-babel 就够了
        => const babel = require('gulp-babel')
      3. 使用 babel() 函数进行压缩的时候
        => 需要传递参数
        => { presets: ['@babel/preset-env'] }
*/
const jsHandler = () => {
  // 书写打包 js 文件的流程
  return gulp
    .src('./src/js/*.js')
    .pipe(babel({ presets: ['@babel/preset-env'] })) // 把 ES6 转换成 ES5 语法
    .pipe(uglify()) // 进行压缩处理
    .pipe(gulp.dest('./dist/js/')) // 放在指定目录内
}

/*
  4. 打包 html 文件的任务
    + 压缩 html 文件的时候
      => 使用一个叫做 gulp-htmlmin 的第三方文件
    + 注意:
      => 这个 gulp-htmlmin 第三方的使用需要传递一个参数
      => 参数是一个对象数据类型, 里面是本次压缩的所有配置项
        { 配置项 }

  扩展 - html 组件
    + 可以在 html 文件打包以前, 进行 html 文件组件的导入
    + 需要依赖一个第三方包叫做 gulp-file-include
    + 使用:
      => 在 gulp 内的使用
        -> 引入以后, 直接使用需要传递参数进行配置
      => 在 html 文件内的使用
        -> 当你需要导入片段的时候, 直接书写 标识符include('basepath 一下的目录结构')
*/
const htmlHandler = () => {
  // 打包 html 文件的 任务流程
  return gulp
    .src('./src/*.html')
    .pipe(fileinclude({  // 进行 html 组件的组装
        // 你的组件文件所存储的路径, 你的 html 片段文件, 存放的目录
        basepath: './src/components/',
        // 你自己定义的特殊标识符
        // 你在html 文件内书写这个标识符的时候, 表示你要使用 fileinclude 语法了
        prefix: '@-@'
      }))
    .pipe(htmlmin({ // 进行压缩处理
      // 表示把多余的空白内容去掉
      collapseWhitespace: true,
      // 表示把布尔类型属性简化书写
      collapseBooleanAttributes: true,
      // 去除双引号
      removeAttributeQuotes: true,
      // 移出空属性
      removeEmptyAttributes: true,
      // 移除注释
      removeComments: true,
      // 移除 script 标签身上默认的 type 属性
      removeScriptTypeAttributes: true,
      // 移出 link 标签和 style 标签身上的默认 type 属性
      removeStyleLinkTypeAttributes: true,
      // 压缩内嵌式 css 样式
      minifyCSS: true,
      // 压缩内嵌式 js 代码
      minifyJS: true
    }))
    .pipe(gulp.dest('./dist/views/')) // 进行转存到指定文件夹内
}

/*
  5. 打包 图片 文件
    + 压缩 图片文件 需要使用一个第三方包
      => 叫做 gulp-imagemin
    + 下载完毕就是一个函数, 直接调用就可以了
*/
const imgHandler = () => {
  // 书写打包 img 文件的流程
  return gulp
    .src('./src/images/*.**')
    .pipe(gulp.dest('./dist/images/')) // 进行转存到指定位置
}

/*
  7. 转存 fonts 文件
    + 不需要压缩, 直接转存就可以了
*/
const fontHandler = () => {
  return gulp
    .src('./src/fonts/*.**')
    .pipe(gulp.dest('./dist/fonts/'))
}

/*
  8. 配置一个删除任务
    + 每次打包之前, 删除 dist 文件夹
    + 按照最新的 src 目录进行打包
    + 删除文件需要用到一个第三方包, 叫做 del
    + 不需要依赖于流
      => 直接调用就可以了
      => del(['你要删除的文件夹'])

*/
const delHandler = () => {
  return del(['./dist/'])
}


const _default = gulp.series(
  delHandler,
  gulp.parallel(cssHandler, htmlHandler, jsHandler, imgHandler, fontHandler),
)

// 导出你创建的所有任务
module.exports = {
  cssHandler,
  jsHandler,
  htmlHandler,
  imgHandler,
  fontHandler,
  delHandler,
  default: _default
}

// 压缩 js 的第三方叫做 gulp-uglify
// 提示: 暂时不要写 es6 语法